#include "client.h"

// 全局变量定义
int logged_in = 0;
char current_username[50] = {0};
int current_directory_id = 0;

int main() {
    printf(CLEAR_SCREEN);
    printf(GREEN_TEXT "+----------------------------------------------------+\n");
    printf("|                云文件管理系统客户端               |\n");
    printf("|                  按任意键启动服务                  |\n");
    printf("+----------------------------------------------------+\n" RESET_TEXT);
    getchar();

    int sockfd = connect_to_server();
    if (sockfd < 0) {
        fprintf(stderr, RED_TEXT "错误: 连接服务器失败，程序退出\n" RESET_TEXT);
        return 1;
    }
    interactive_main_menu(sockfd);
    close(sockfd);
    return 0;
}

void interactive_main_menu(int sockfd) {
    int choice;
    char input[10];
    while (1) {
        if (!logged_in) {
            printf(CLEAR_SCREEN);
            printf(BLUE_TEXT "+----------------------------------------------------+\n");
            printf("|                   用户登录页面                     |\n");
            printf("+----------------------------------------------------+\n" RESET_TEXT);
            printf("  1. 注册新账户\n  2. 登录系统\n  3. 退出程序\n");
            printf(YELLOW_TEXT "请选择操作 (1-3): " RESET_TEXT);
            fgets(input, sizeof(input), stdin);
            choice = atoi(input);
            switch(choice) {
                case 1: handle_register(sockfd); break;
                case 2: 
                    if (handle_login(sockfd)) {
                        printf(GREEN_TEXT "\n登录成功! 即将进入主菜单...\n" RESET_TEXT);
                        sleep(1);
                    } else {
                        printf(RED_TEXT "\n登录失败! 用户名或密码错误\n" RESET_TEXT);
                        sleep(2);
                    }
                    break;
                case 3: close(sockfd); exit(0);
                default: printf(RED_TEXT "无效选择\n" RESET_TEXT); sleep(1);
            }
        } else {
            printf(CLEAR_SCREEN);
            printf(GREEN_TEXT "+----------------------------------------------------+\n");
            printf("|                 云文件管理系统主菜单               |\n");
            printf("|              欢迎您, %-25s |\n", current_username);
            if (current_directory_id > 0) {
                printf("|              当前目录: %-25d |\n", current_directory_id);
            }
            printf("+----------------------------------------------------+\n" RESET_TEXT);
            printf("  1. 文件上传\n  2. 文件下载\n  3. 文件列表\n");
            printf("  4. 文件删除\n  5. 创建文件夹\n  6. 切换目录\n  7. 退出登录\n");
            printf(YELLOW_TEXT "请选择操作 (1-7): " RESET_TEXT);
            fgets(input, sizeof(input), stdin);
            choice = atoi(input);
            switch(choice) {
                case 1: handle_file_upload(sockfd); break;
                case 2: handle_file_download(sockfd); break;
                case 3: handle_file_list(sockfd); break;
                case 4: handle_file_delete(sockfd); break;
                case 5: handle_mkdir(sockfd); break;
                case 6: change_directory(sockfd); break;
                case 7: handle_logout(sockfd); return;
                default: printf(RED_TEXT "无效选择\n" RESET_TEXT); sleep(1);
            }
        }
    }
}

void get_password_input(char *buffer, size_t size) {
    struct termios old_term, new_term;
    tcgetattr(STDIN_FILENO, &old_term);
    new_term = old_term;
    new_term.c_lflag &= ~ECHO;
    if (tcsetattr(STDIN_FILENO, TCSANOW, &new_term) != 0) exit(EXIT_FAILURE);
    printf("密码: ");
    fgets(buffer, size, stdin);
    buffer[strcspn(buffer, "\n")] = '\0';
    tcsetattr(STDIN_FILENO, TCSANOW, &old_term);
    printf("\n");
}

void press_enter_to_continue(void) {
    printf(YELLOW_TEXT "\n按Enter键继续..." RESET_TEXT);
    while (getchar() != '\n');
    getchar();
}

void handle_register(int sockfd) {
    char username[50], password[50];
    printf(CLEAR_SCREEN);
    printf(BLUE_TEXT "+----------------------------------------------------+\n");
    printf("|                      用户注册                       |\n");
    printf("+----------------------------------------------------+\n" RESET_TEXT);
    printf("用户名: ");
    fgets(username, sizeof(username), stdin);
    username[strcspn(username, "\n")] = 0;
    get_password_input(password, sizeof(password));
    char command[512];
    snprintf(command, sizeof(command), "REGISTER %s %s\n", username, password);
    send_command(sockfd, command);
    receive_response(sockfd);
    press_enter_to_continue();
}

int handle_login(int sockfd) {
    char username[50], password[50];
    printf(CLEAR_SCREEN);
    printf(BLUE_TEXT "+----------------------------------------------------+\n");
    printf("|                      用户登录                       |\n");
    printf("+----------------------------------------------------+\n" RESET_TEXT);
    printf("用户名: ");
    fgets(username, sizeof(username), stdin);
    username[strcspn(username, "\n")] = 0;
    get_password_input(password, sizeof(password));
    char command[256];
    snprintf(command, sizeof(command), "LOGIN %s %s\n", username, password);
    send_command(sockfd, command);
    char buffer[BUFFER_SIZE] = {0};
    read(sockfd, buffer, BUFFER_SIZE);
    printf("\n服务器响应:\n%s\n", buffer);
    if (strstr(buffer, "成功")) {
        strncpy(current_username, username, sizeof(current_username));
        logged_in = 1;
        current_directory_id = 0;
        return 1;
    }
    return 0;
}

// client.h 保持不变

// client.c 修改 handle_file_upload 函数
void handle_file_upload(int sockfd) {
    char filepath[PATH_MAX];
    printf(CLEAR_SCREEN);
    printf(BLUE_TEXT "+----------------------------------------------------+\n");
    printf("|                      文件上传                       |\n");
    printf("|                  用户: %-29s |\n", current_username);
    if (current_directory_id > 0) {
        printf("|                  目录: %-29d |\n", current_directory_id);
    }
    printf("+----------------------------------------------------+\n" RESET_TEXT);
    printf("请输入本地文件完整路径: ");
    fgets(filepath, sizeof(filepath), stdin);
    filepath[strcspn(filepath, "\n")] = 0;
    
    FILE *file = fopen(filepath, "rb");
    if (!file) {
        perror(RED_TEXT "文件打开失败" RESET_TEXT);
        press_enter_to_continue();
        return;
    }
    
    // 获取文件信息
    fseek(file, 0, SEEK_END);
    long file_size = ftell(file);
    fseek(file, 0, SEEK_SET);
    char *filename = basename(filepath);
    
    // 发送上传命令和文件信息
    char command[512];
    snprintf(command, sizeof(command), "UPLOAD %s %d %s %ld\n", 
             current_username, current_directory_id, filename, file_size);
    send_command(sockfd, command);
    
    // 接收服务器确认
    char response[256];
    read(sockfd, response, sizeof(response));
    if (strstr(response, "READY") == NULL) {
        printf(RED_TEXT "服务器未准备好接收文件\n" RESET_TEXT);
        fclose(file);
        press_enter_to_continue();
        return;
    }
    
    // 开始上传文件内容
    char buffer[BUFFER_SIZE];
    size_t bytes_read;
    long total_bytes = 0;
    time_t start_time = time(NULL);
    
    while ((bytes_read = fread(buffer, 1, BUFFER_SIZE, file)) > 0) {
        if (write(sockfd, buffer, bytes_read) < 0) break;
        total_bytes += bytes_read;
        float progress = (float)total_bytes / file_size * 100;
        time_t current_time = time(NULL);
        double elapsed = difftime(current_time, start_time);
        double speed = (elapsed > 0) ? (total_bytes / (1024.0 * elapsed)) : 0;
        printf("\r上传进度: %.2f%% | 已发送: %.2fMB | 速度: %.2f KB/s", 
               progress, total_bytes / (1024.0 * 1024.0), speed);
        fflush(stdout);
    }
    printf("\n");
    fclose(file);
    
    // 接收最终响应
    receive_response(sockfd);
    press_enter_to_continue();
}

void handle_file_download(int sockfd) {
    char filename[256];
    printf(CLEAR_SCREEN);
    printf(BLUE_TEXT "+----------------------------------------------------+\n");
    printf("|                      文件下载                       |\n");
    printf("|                  用户: %-29s |\n", current_username);
    if (current_directory_id > 0) {
        printf("|                  目录: %-29d |\n", current_directory_id);
    }
    printf("+----------------------------------------------------+\n" RESET_TEXT);
    printf("请输入要下载的文件名: ");
    fgets(filename, sizeof(filename), stdin);
    filename[strcspn(filename, "\n")] = 0;
    
    char command[256];
    snprintf(command, sizeof(command), "DOWNLOAD %s %d %s\n", 
             current_username, current_directory_id, filename);
    send_command(sockfd, command);
    
    char buffer[BUFFER_SIZE] = {0};
    ssize_t bytes_read;
    long file_size = 0;
    long total_bytes = 0;
    
    // 读取文件大小
    bytes_read = read(sockfd, buffer, BUFFER_SIZE - 1);
    if (bytes_read > 0) {
        buffer[bytes_read] = '\0';
        if (sscanf(buffer, "SIZE %ld", &file_size) == 1) {
            printf("文件大小: %.2f MB\n", file_size / (1024.0 * 1024.0));
            total_bytes = file_size;
        }
    }
    
    // 创建本地文件
    char local_path[PATH_MAX];
    snprintf(local_path, PATH_MAX, "%s_download", filename);
    FILE *file = fopen(local_path, "wb");
    if (!file) {
        perror(RED_TEXT "本地文件创建失败" RESET_TEXT);
        return;
    }
    
    time_t start_time = time(NULL);
    while ((bytes_read = read(sockfd, buffer, BUFFER_SIZE)) > 0) {
        fwrite(buffer, 1, bytes_read, file);
        total_bytes -= bytes_read;
        float progress = 100.0 - ((float)total_bytes / file_size * 100);
        time_t current_time = time(NULL);
        double elapsed = difftime(current_time, start_time);
        double speed = (elapsed > 0) ? ((file_size - total_bytes) / (1024.0 * elapsed)) : 0;
        printf("\r下载进度: %.2f%% | 速度: %.2f KB/s", progress, speed);
        fflush(stdout);
    }
    printf("\n");
    fclose(file);
    receive_response(sockfd);
    press_enter_to_continue();
}

void handle_file_list(int sockfd) {
    char command[256];
    snprintf(command, sizeof(command), "LIST %s %d\n", 
             current_username, current_directory_id);
    send_command(sockfd, command);
    
    char buffer[BUFFER_SIZE] = {0};
    ssize_t bytes_read;
    printf(CLEAR_SCREEN);
    printf(BLUE_TEXT "+----------------------------------------------------+\n");
    printf("|                      文件列表                       |\n");
    printf("|                  用户: %-29s |\n", current_username);
    if (current_directory_id > 0) {
        printf("|                  目录: %-29d |\n", current_directory_id);
    }
    printf("+----------------------------------------------------+\n" RESET_TEXT);
    
    while ((bytes_read = read(sockfd, buffer, BUFFER_SIZE - 1)) > 0) {
        buffer[bytes_read] = '\0';
        if (strstr(buffer, "END_OF_LIST")) {
            break;
        }
        printf("%s", buffer);
    }
    press_enter_to_continue();
}

void handle_file_delete(int sockfd) {
    char filename[256];
    printf(CLEAR_SCREEN);
    printf(BLUE_TEXT "+----------------------------------------------------+\n");
    printf("|                      文件删除                       |\n");
    printf("|                  用户: %-29s |\n", current_username);
    if (current_directory_id > 0) {
        printf("|                  目录: %-29d |\n", current_directory_id);
    }
    printf("+----------------------------------------------------+\n" RESET_TEXT);
    printf("请输入要删除的文件名: ");
    fgets(filename, sizeof(filename), stdin);
    filename[strcspn(filename, "\n")] = 0;
    
    char command[256];
    snprintf(command, sizeof(command), "DELETE %s %d %s\n", 
             current_username, current_directory_id, filename);
    send_command(sockfd, command);
    receive_response(sockfd);
    press_enter_to_continue();
}

void handle_mkdir(int sockfd) {
    char dirname[256];
    printf(CLEAR_SCREEN);
    printf(BLUE_TEXT "+----------------------------------------------------+\n");
    printf("|                    创建文件夹                      |\n");
    printf("|                  用户: %-29s |\n", current_username);
    if (current_directory_id > 0) {
        printf("|                  当前目录: %-29d |\n", current_directory_id);
    }
    printf("+----------------------------------------------------+\n" RESET_TEXT);
    printf("请输入新目录名称: ");
    fgets(dirname, sizeof(dirname), stdin);
    dirname[strcspn(dirname, "\n")] = 0;
    
    char command[256];
    snprintf(command, sizeof(command), "MKDIR %s %d %s\n", 
             current_username, current_directory_id, dirname);
    send_command(sockfd, command);
    receive_response(sockfd);
    press_enter_to_continue();
}

void change_directory(int sockfd) {
    char dir_id[20];
    printf(CLEAR_SCREEN);
    printf(BLUE_TEXT "+----------------------------------------------------+\n");
    printf("|                      切换目录                       |\n");
    printf("|                  用户: %-29s |\n", current_username);
    printf("|                  当前目录: %-29d |\n", current_directory_id);
    printf("+----------------------------------------------------+\n" RESET_TEXT);
    printf("请输入目录ID (0表示根目录): ");
    fgets(dir_id, sizeof(dir_id), stdin);
    dir_id[strcspn(dir_id, "\n")] = 0;
    
    int new_dir_id = atoi(dir_id);
    if (new_dir_id >= 0) {
        current_directory_id = new_dir_id;
        printf(GREEN_TEXT "已切换到目录 %d\n" RESET_TEXT, current_directory_id);
    } else {
        printf(RED_TEXT "无效的目录ID\n" RESET_TEXT);
    }
    sleep(1);
}

void handle_logout(int sockfd) {
    char command[256];
    snprintf(command, sizeof(command), "LOGOUT %s\n", current_username);
    send_command(sockfd, command);
    receive_response(sockfd);
    logged_in = 0;
    current_directory_id = 0;
    memset(current_username, 0, sizeof(current_username));
    printf(GREEN_TEXT "\n已退出登录!\n" RESET_TEXT);
    sleep(1);
}

int connect_to_server() {
    int sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd < 0) {
        perror(RED_TEXT "创建套接字失败" RESET_TEXT);
        return -1;
    }
    struct sockaddr_in serv_addr;
    memset(&serv_addr, 0, sizeof(serv_addr));
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_port = htons(SERVER_PORT);
    if (inet_pton(AF_INET, SERVER_IP, &serv_addr.sin_addr) <= 0) {
        printf(RED_TEXT "无效的服务器地址 %s\n" RESET_TEXT, SERVER_IP);
        close(sockfd);
        return -1;
    }
    printf("正在连接服务器 %s:%d...\n", SERVER_IP, SERVER_PORT);
    if (connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) {
        perror(RED_TEXT "连接失败" RESET_TEXT);
        close(sockfd);
        return -1;
    }
    printf(GREEN_TEXT "连接成功!\n" RESET_TEXT);
    return sockfd;
}

void send_command(int sockfd, const char *command) {
    if (write(sockfd, command, strlen(command)) < 0) {
        perror(RED_TEXT "发送失败" RESET_TEXT);
    }
}

void receive_response(int sockfd) {
    char buffer[BUFFER_SIZE] = {0};
    ssize_t bytes_read;
    while ((bytes_read = read(sockfd, buffer, BUFFER_SIZE - 1)) > 0) {
        buffer[bytes_read] = '\0';
        if (strstr(buffer, "END_OF_RESPONSE")) {
            printf("\n服务器响应:\n%s\n", buffer);
            break;
        }
        printf("%s", buffer);
    }
}